座æšç³»å€æãçè§£ã»ç¿åŸããWebXRã«ããã空éã³ã³ãã¥ãŒãã£ã³ã°ã®è€éããå æããŸãããããã®å æ¬çã¬ã€ãã¯ãã¯ãŒã«ããããŒã«ã«ããã¥ãŒã¹ããŒã¹ãæ·±ãæãäžããã·ãŒã ã¬ã¹ã§æ²¡å ¥æã®ããXRäœéšã®åµé ã«äžå¯æ¬ ãªç¥èãæäŸããŸãã
WebXR空éã®ãã¹ã¿ãŒïŒåº§æšç³»å€æã®æ·±æã解説
WebXRã®äžçã¯æ¥éã«é²åããŠãããç©ççãªå¢çãè¶ ããæ²¡å ¥äœéšã®ããã®åäŸã®ãªãæ©äŒãæäŸããŠããŸããæ±äº¬ããã¢ã¯ã»ã¹å¯èœãªããŒãã£ã«ãªã¢ãªãã£ã®çŸè¡é€šãã¢ãŒããã³ãã³ã®é¡§å®¢åãã®æ¡åŒµçŸå®è£œåããžã¥ã¢ã©ã€ãŒãŒã·ã§ã³ããŸãã¯ã°ããŒãã«ã«å±éãããã€ã³ã¿ã©ã¯ãã£ããªãã¬ãŒãã³ã°ã·ãã¥ã¬ãŒã·ã§ã³ãéçºããŠããå Žåã§ããé åçãªXRã¢ããªã±ãŒã·ã§ã³ã®åºç€ã¯ã3D空éã®çè§£ãšæäœã«ãããŸãããã®äžå¿ã«ããã®ã座æšç³»å€æã§ããå ç¢ã§çŽæçããã€ã°ããŒãã«ã«äºææ§ã®ããWebXRäœéšãåµãåºãããšããéçºè ã«ãšã£ãŠãç°ãªã座æšç³»ãã©ã®ããã«çžäºäœçšãããããã£ãããšææ¡ããããšã¯ãæçã§ããã ãã§ãªããäžå¯æ¬ ãªã®ã§ãã
åºæ¬çãªèª²é¡ïŒç©ºéã«å¯Ÿããç°ãªãèŠç¹
ããªããæŒåãç£ç£ããŠãããšæ³åããŠã¿ãŠãã ãããèå°äžã«ã¯ä¿³åªãããããããããç¬èªã®ããŒãœãã«ã¹ããŒã¹ãšåããæã£ãŠããŸãããŸããèå°å šäœã«ãç¬èªã®åºå®ç¹ãšå¯žæ³ããããŸãããããŠãç¹å®ã®èŠç¹ããæŒåã芳å¯ãã芳客ã®èŠç¹ããããŸãããããã¯ãããããäœçœ®ãšåããå®çŸ©ããç¬èªã®æ¹æ³ãæã€ãç°ãªãã空éãã衚ããŠããŸãã
ã³ã³ãã¥ãŒã¿ã°ã©ãã£ãã¯ã¹ãšXRã§ã¯ããã®æŠå¿µãåæ ãããŠããŸãããªããžã§ã¯ãã¯ãããèªèº«ã®ããŒã«ã«ç©ºéïŒã¢ãã«ç©ºéãšãåŒã°ããŸãïŒã«ååšããŸãããããã®ãªããžã§ã¯ãã¯ããã倧ããªã¯ãŒã«ã空éå ã«é 眮ãããä»ã®ãã¹ãŠãšã®çžå¯Ÿçãªäœçœ®ãå転ãã¹ã±ãŒã«ãå®çŸ©ãããŸããæåŸã«ãVRãããã»ãããARããã€ã¹ãéãããŠãŒã¶ãŒã®èŠç¹ããã¥ãŒç©ºéïŒãŸãã¯ã«ã¡ã©ç©ºéïŒãå®çŸ©ããã¯ãŒã«ãã®ã©ã®éšåãèŠãããããããŠãããã©ã®ããã«2Dã¹ã¯ãªãŒã³ã«æåœ±ãããããæ±ºå®ããŸãã
課é¡ã¯ããããã®ç©ºééã§æ å ±ã倿ããå¿ èŠããããšãã«çããŸããç¬èªã®ãããŒã«ã«ãã¢ãã«åº§æšã§å®çŸ©ãããä»®æ³ãªããžã§ã¯ãã®äœçœ®ã¯ããã¹ãŠã®ãªããžã§ã¯ããå ±åãããã¯ãŒã«ããã§ã©ã®ããã«æ£ããã¬ã³ããªã³ã°ãããã®ã§ããããïŒãããŠããã®ã¯ãŒã«ã空éã¯ããŠãŒã¶ãŒã®çŸåšã®èŠç·ãšäœçœ®ã«åãããŠã©ã®ããã«å€æãããã®ã§ããããïŒ
WebXRã«ãããäž»èŠãªåº§æšç³»ã®çè§£
WebXRã¢ããªã±ãŒã·ã§ã³ã¯ãã»ãšãã©ã®3Dã°ã©ãã£ãã¯ã¹ãšã³ãžã³ãšåæ§ã«ã座æšç³»ã®éå±€ã«äŸåããŠããŸãã广çãªå€æã®ããã«ã¯ããããããçè§£ããããšãéèŠã§ãã
1. ããŒã«ã«ç©ºéïŒã¢ãã«ç©ºéïŒ
ããã¯ãåã ã®3Dã¢ãã«ããªããžã§ã¯ãã®ãã€ãã£ããªåº§æšç³»ã§ãã3Dã¢ãŒãã£ã¹ããã¡ãã·ã¥ïŒæ€ åããã£ã©ã¯ã¿ãŒãå®å®è¹ãªã©ïŒãäœæãããšãããã®é ç¹ã¯èªèº«ã®åç¹ïŒ0,0,0ïŒãåºæºã«å®çŸ©ãããŸãããªããžã§ã¯ãã®åããšã¹ã±ãŒã«ããã®ç©ºéå ã§å®çŸ©ãããŸããäŸãã°ãæ€ åã®ã¢ãã«ã¯ãåºéšãåç¹ã«ããçŽç«ããç¶æ ã§äœæããããããããŸããããã®å¯žæ³ã¯ãèªèº«ã®ããŠã³ãã£ã³ã°ããã¯ã¹ã«å¯ŸããŠçžå¯Ÿçã§ãã
äž»ãªç¹åŸŽïŒ
- åç¹ïŒ0,0,0ïŒã¯ãªããžã§ã¯ãã®äžå¿ãŸãã¯åç §ç¹ã«ãããŸãã
- é ç¹ã¯ãã®åç¹ãåºæºã«å®çŸ©ãããŸãã
- ä»ã®ãªããžã§ã¯ãããŠãŒã¶ãŒã®èŠç¹ããã¯ç¬ç«ããŠããŸãã
2. ã¯ãŒã«ã空é
ã¯ãŒã«ã空éã¯ã3Dã·ãŒã³å ã®ãã¹ãŠã®ãªããžã§ã¯ããé 眮ãããäœçœ®ã¥ããããçµ±äžãããã°ããŒãã«ãªåº§æšç³»ã§ããããã¯ããªãã®XRäœéšãç¹°ãåºãããããèå°ãã§ããWebXRã·ãŒã³ã«ã¢ãã«ãã€ã³ããŒããããšãã倿ïŒå¹³è¡ç§»åãåè»¢ãæ¡å€§çž®å°ïŒãé©çšããŠãããŒã«ã«ç©ºéããã¯ãŒã«ã空éã«ç§»åãããŸããäŸãã°ãæ€ åã®ã¢ãã«ãããŒã«ã«ç©ºéã®åç¹ã§äœæãããå Žåããããã¯ãŒã«ã空éã®ç¹å®ã®äœçœ®ïŒäŸãã°ããªãã³ã°ã«ãŒã ã®ã·ãŒã³å ïŒã«ç§»åãããçªã®æ¹ãåãããã«å転ããããããããŸããã
äž»ãªç¹åŸŽïŒ
- ã·ãŒã³å šäœã§åäžã®äžè²«ãã座æšç³»ã§ãã
- ãã¹ãŠã®ãªããžã§ã¯ãéã®ç©ºéçé¢ä¿ãå®çŸ©ããŸãã
- åç¹ïŒ0,0,0ïŒã¯éåžžãã·ãŒã³ã®äžå¿ç¹ã衚ããŸãã
3. ãã¥ãŒç©ºéïŒã«ã¡ã©ç©ºéïŒ
ãã¥ãŒç©ºéã¯ãã«ã¡ã©ãŸãã¯ãŠãŒã¶ãŒã®èŠç¹ããã®åº§æšç³»ã§ããã·ãŒã³å ã®ãã¹ãŠããã«ã¡ã©ãåç¹ïŒ0,0,0ïŒã«ãããç¹å®ã®è»žïŒå€ãã®å Žåãè² ã®Z軞ïŒãåãããã«å€æãããŸãããã®å€æã¯ããã¹ãŠã®ãªããžã§ã¯ãã2Dã¹ã¯ãªãŒã³ã«æåœ±ã§ããåç §ãã¬ãŒã ã«æã¡èŸŒããããã¬ã³ããªã³ã°ã«ãšã£ãŠéåžžã«éèŠã§ãã
äž»ãªç¹åŸŽïŒ
- ã«ã¡ã©ã¯åç¹ïŒ0,0,0ïŒã«é 眮ãããŸãã
- äž»èŠãªèŠç·æ¹åã¯ãéåžžãè² ã®Zè»žã«æ²¿ã£ãŠããŸãã
- ãªããžã§ã¯ãã¯ãã«ã¡ã©ã®ãåæ¹ãããäžæ¹ããã峿¹ãã®æ¹åãåºæºã«ããŠé 眮ãããŸãã
4. ã¯ãªãã空éïŒæ£èŠåããã€ã¹åº§æš - NDCïŒ
ãã¥ãŒç©ºéãžã®å€æåŸããªããžã§ã¯ãã¯ããã«ã¯ãªãã空éã«å°åœ±ãããŸããããã¯ãéèŠæåœ±ãé©çšããã忬¡åº§æšç³»ã§ãããã¯ãªããã³ã°å¹³é¢ãïŒè¿å¹³é¢ãšé å¹³é¢ïŒã衚瀺å¯èœãªèŠéå°ãå®çŸ©ãããã®èŠéå°ã®å€ã«ãããã®ã¯ãã¹ãŠãã¯ãªããããããŸããå°åœ±åŸã座æšã¯éåžžãç«æ¹äœïŒå軞ã§-1ãã+1ãŸã§ïŒã«æ£èŠåãããå ã®å°åœ±ãã©ã¡ãŒã¿ããç¬ç«ãããã®ã«ãªããŸãã
äž»ãªç¹åŸŽïŒ
- 忬¡åº§æšïŒéåžžã¯4DïŒxãyãzãwïŒã
- èŠéå°å ã®ãªããžã§ã¯ãããã®ç©ºéã«ãããã³ã°ãããŸãã
- 座æšã¯éåžžãæ£èŠåãã¥ãŒããªã¥ãŒã ïŒäŸïŒç«æ¹äœïŒã«æ£èŠåãããŸãã
5. ã¹ã¯ãªãŒã³ç©ºé
æåŸã«ãïŒéèŠé€ç®åŸã®ïŒã¯ãªãã空éã®åº§æšã¯ããŠãŒã¶ãŒã®ãã£ã¹ãã¬ã€äžã®ãã¯ã»ã«ã«å¯Ÿå¿ããã¹ã¯ãªãŒã³ç©ºéã«ãããã³ã°ãããŸããã¹ã¯ãªãŒã³ç©ºéã®åç¹ã¯éåžžããã¥ãŒããŒãã®å·ŠäžãŸãã¯å·Šäžé ã§ãããXã¯å³ã«ãYã¯äžïŒãŸãã¯èŠçŽã«ãã£ãŠã¯äžïŒã«å¢å ããŸããããããæçµçãª2Dç»åãã¬ã³ããªã³ã°ããã空éã§ãã
äž»ãªç¹åŸŽïŒ
- ãã£ã¹ãã¬ã€äžã®ãã¯ã»ã«åº§æšã
- åç¹ã¯å·ŠäžãŸãã¯å·Šäžã«ãªããŸãã
- ã¬ã³ããªã³ã°ãããåºåã«çŽæ¥å¯Ÿå¿ããŸãã
倿è¡åã®å
ãªããžã§ã¯ããããŒã«ã«ç©ºéããã¯ãŒã«ã空éãžããããŠãã¥ãŒç©ºéãžãæçµçã«ã¹ã¯ãªãŒã³ç©ºéãžç§»åãããã«ã¯ã©ãããã°ããã®ã§ããããïŒçãã¯å€æè¡åã«ãããŸãã3Dã°ã©ãã£ãã¯ã¹ã§ã¯ã倿ïŒå¹³è¡ç§»åãåè»¢ãæ¡å€§çž®å°ïŒã¯æ°åŠçã«è¡åãšããŠè¡šçŸãããŸããç¹ã®åº§æšã«å€æè¡åãä¹ç®ããããšã§ããã®ç¹ã广çã«æ°ãã座æšç³»ã«å€æããŸãã
WebXRéçºã«ãšã£ãŠãgl-matrixã©ã€ãã©ãªã¯äžå¯æ¬ ãªããŒã«ã§ããããã¯ã3D倿ãæäœããããã«å¿ é ã§ãããäžè¬çãªè¡åããã³ãã¯ãã«æŒç®ã®é«æ§èœãªJavaScriptå®è£ ãæäŸããŸãã
è¡åã®çš®é¡ãšãã®åœ¹å²ïŒ
- ã¢ãã«è¡åïŒãªããžã§ã¯ãè¡åïŒïŒãã®è¡åã¯ããªããžã§ã¯ãããã®ããŒã«ã«ç©ºéããã¯ãŒã«ã空éã«å€æããŸããã·ãŒã³å ã§ã®ãªããžã§ã¯ãã®äœçœ®ãå転ãã¹ã±ãŒã«ãå®çŸ©ããŸããä»®æ³ã®ãªãã³ã°ã«ãŒã ã®ç¹å®ã®å Žæã«æ€ åã®ã¢ãã«ãé 眮ãããå Žåãããªãã¯ãã®ã¢ãã«è¡åãäœæããŠããããšã«ãªããŸãã
- ãã¥ãŒè¡åïŒã«ã¡ã©è¡åïŒïŒãã®è¡åã¯ãç¹ãã¯ãŒã«ã空éãããã¥ãŒç©ºéã«å€æããŸããæ¬è³ªçã«ãã¯ãŒã«ãå ã§ã®ã«ã¡ã©ã®äœçœ®ãšåããèšè¿°ããŸããããã¯ã«ã¡ã©ã«å¯ŸããŠã¯ãŒã«ãããé 眮ãããŸããWebXRã§ã¯ããã®è¡åã¯éåžžãXRããã€ã¹ã®ããŒãºïŒäœçœ®ãšåãïŒããå°åºãããŸãã
- å°åœ±è¡åïŒãã®è¡åã¯ãç¹ããã¥ãŒç©ºéããã¯ãªãã空éã«å€æããŸããã«ã¡ã©ã®èŠéå°ïŒèŠããç¯å²ã®ããªã¥ãŒã ïŒãå®çŸ©ããé ãã®ãªããžã§ã¯ããå°ããèŠããããã«ããé è¿å¹æãé©çšããŸããããã¯éåžžãã«ã¡ã©ã®èŠéè§ãã¢ã¹ãã¯ãæ¯ãããã³è¿ïŒé ã¯ãªããã³ã°å¹³é¢ã«åºã¥ããŠèšå®ãããŸãã
倿ãã€ãã©ã€ã³ïŒããŒã«ã«ããã¹ã¯ãªãŒã³ãž
ãªããžã§ã¯ãã®ããŒã«ã«ç©ºéã«ããé ç¹ããæçµçãªã¹ã¯ãªãŒã³äžã®äœçœ®ãŸã§ã®å®å šãªå€æã¯ã次ã®ãã€ãã©ã€ã³ã«åŸããŸãïŒ
ããŒã«ã«ç©ºé â ã¯ãŒã«ã空é â ãã¥ãŒç©ºé â ã¯ãªãã空é â ã¹ã¯ãªãŒã³ç©ºé
ããã¯ãé ç¹ã®åº§æšã«å¯Ÿå¿ããè¡åãæ£ããé åºã§ä¹ç®ããããšã«ãã£ãŠéæãããŸãïŒ
é ç¹ïŒããŒã«ã«ç©ºéïŒÃ ã¢ãã«è¡å à ãã¥ãŒè¡å à å°åœ±è¡å = é ç¹ïŒã¯ãªãã空éïŒ
æ°åŠçã«ã¯ãv_localãããŒã«ã«ç©ºéã®é ç¹ã§ãããM_modelãM_viewãM_projectionãããããã®è¡åã§ããå ŽåïŒ
v_clip = M_projection à M_view à M_model à v_local
泚æïŒã°ã©ãã£ãã¯ã¹ã§ã¯ãè¡åã¯ãã°ãã°ãã¯ãã«ã«è¡åãä¹ç®ããããšã«ãã£ãŠé©çšãããŸããä¹ç®ã®é åºã¯éèŠã§ããã䜿çšãããè¡åã®èŠçŽïŒäŸïŒè¡åªå
vs. ååªå
ïŒã«äŸåããŸããM_projection à M_view à M_modelãšããé åºã¯ããã¯ãã«ãåãã¯ãã«ãšããŠæ±ããã倿ãè¡å à ãã¯ãã«ãšããŠé©çšãããå Žåã«äžè¬çã§ãã
WebXRã§ã®å®è·µçãªå®è£
WebXR APIã¯ã倿ã«å¿
èŠãªããŒãºæ
å ±ãžã®ã¢ã¯ã»ã¹ãæäŸããŸããXRFrame.getViewerPose()ã¡ãœããããã®äžå¿ãšãªããŸããããã¯XRViewerPoseãªããžã§ã¯ããè¿ãããã®äžã«ã¯XRViewãªããžã§ã¯ãã®é
åãå«ãŸããŠããŸããåXRViewã¯çæ¹ã®ç®ã®èŠç¹ã衚ããã¬ã³ããªã³ã°ã«å¿
èŠãªãã¥ãŒè¡åãšå°åœ±è¡åãæäŸããŸãã
WebXRã§è¡åãååŸããïŒ
XRViewãªããžã§ã¯ãã«ã¯ãæã
ã®å€æãã€ãã©ã€ã³ã«ãšã£ãŠäžå¯æ¬ ãª2ã€ã®äž»èŠãªè¡åãå«ãŸããŠããŸãïŒ
viewMatrixïŒããã¯ãã¥ãŒè¡åã§ããã¯ãŒã«ã座æšãã«ã¡ã©ã®ãã¥ãŒç©ºéã«å€æããŸããprojectionMatrixïŒããã¯å°åœ±è¡åã§ãããã¥ãŒåº§æšãã¯ãªãã空éã«å€æããŸãã
ãªããžã§ã¯ããç»é¢äžã®æ£ããäœçœ®ãšåãã§ã¬ã³ããªã³ã°ããããã«ã¯ãéåžžãæ¬¡ã®æé ãå¿ èŠã§ãïŒ
- ãªããžã§ã¯ãã®ã¢ãã«è¡åãå®çŸ©ããŸãããã®è¡åã¯ãã¯ãŒã«ã空éã«ããããã®äœçœ®ãå転ãã¹ã±ãŒã«ã衚ããŸãããã®è¡åã¯ãå¹³è¡ç§»åãåè»¢ãæ¡å€§çž®å°ã®æäœïŒäŸïŒ
gl-matrix.mat4.create()ãgl-matrix.mat4.translate()ãgl-matrix.mat4.rotate()ãgl-matrix.mat4.scale()ã䜿çšïŒãçšããŠæ§ç¯ããŸãã - çŸåšã®ãã¬ãŒã ã®ãã¥ãŒè¡åãšå°åœ±è¡åã
XRViewãªããžã§ã¯ãããååŸããŸãã - ãããã®è¡åãçµåããŸããæçµçãªã¢ãã«ã»ãã¥ãŒã»ãããžã§ã¯ã·ã§ã³ïŒMVPïŒè¡åã¯éåžžãæ¬¡ã®ããã«èšç®ãããŸãïŒ
MVP = å°åœ±è¡å à ãã¥ãŒè¡å à ã¢ãã«è¡åã - ãã®MVPè¡åãã·ã§ãŒããŒã«æž¡ããŸããã·ã§ãŒããŒã¯ããã®è¡åã䜿çšããŠé ç¹äœçœ®ãããŒã«ã«ç©ºéããã¯ãªãã空éã«å€æããŸãã
äŸïŒã¯ãŒã«ã空éã§ã®ãªããžã§ã¯ãã®é çœ®ãšæ¹åä»ã
ä»®æ³ã®å°çåã®3Dã¢ãã«ããããšããŸãããããä»®æ³ã®éšå±ã®äžå€®ã«é 眮ãããã£ãããšå転ãããããšããŸãã
ãŸãããã®ã¢ãã«è¡åãäœæããŸãïŒ
// Assuming 'glMatrix' is imported and available
const modelMatrix = glMatrix.mat4.create();
// Position the globe in the center of the world space (e.g., at origin)
glMatrix.mat4.identity(modelMatrix); // Start with an identity matrix
glMatrix.mat4.translate(modelMatrix, modelMatrix, [0, 1.5, -3]); // Move it slightly forward and up
// Add a slow rotation around the Y-axis
const rotationAngle = performance.now() / 10000; // Rotate slowly based on time
glMatrix.mat4.rotateY(modelMatrix, modelMatrix, rotationAngle);
// You might also apply scaling if needed
// glMatrix.mat4.scale(modelMatrix, modelMatrix, [scaleFactor, scaleFactor, scaleFactor]);
次ã«ãã¬ã³ããªã³ã°ã«ãŒãå
ã§ãåXRViewã«å¯ŸããŠïŒ
// Inside your XR animation loop
const viewerPose = frame.getViewerPose(referenceSpace);
if (viewerPose) {
for (const view of viewerPose.views) {
const viewMatrix = view.viewMatrix;
const projectionMatrix = view.projectionMatrix;
// Combine matrices: MVP = Projection * View * Model
const mvpMatrix = glMatrix.mat4.create();
glMatrix.mat4.multiply(mvpMatrix, projectionMatrix, viewMatrix);
glMatrix.mat4.multiply(mvpMatrix, mvpMatrix, modelMatrix); // Apply model matrix last
// Set the MVP matrix in your shader uniforms
// glUniformMatrix4fv(uniformLocation, false, mvpMatrix);
// ... render your globe using this MVP matrix ...
}
}
ãã®ããã»ã¹ã«ãããããŒã«ã«åº§æšã§å®çŸ©ãããå°çåããã¯ãŒã«ãå ã§æ£ããé 眮ãããæ¹åä»ããããæ¡å€§çž®å°ãããæ¬¡ã«ãŠãŒã¶ãŒã®èŠç¹ããèŠãããæçµçã«ã¹ã¯ãªãŒã³ã«æåœ±ãããããšãä¿èšŒãããŸãã
ã€ã³ã¿ã©ã¯ãã£ããã£ã®ããã®åº§æšç³»åŠç
ã€ã³ã¿ã©ã¯ãã£ããã£ã¯ããã°ãã°ãŠãŒã¶ãŒå ¥åïŒã³ã³ãããŒã©ãŒã®ããŒãºãèŠç·æ¹åãªã©ïŒãã·ãŒã³ã®åº§æšç³»ã«å€æãããããã®éãè¡ã£ããããå¿ èŠããããŸãã
ã³ã³ãããŒã©ãŒã®ããŒãºïŒ
XRFrame.getController(inputSource)ã¯ãã³ã³ãããŒã©ãŒã®ããŒãºãæäŸããŸãããã®ããŒãºã¯XRReferenceSpaceïŒäŸïŒãlocalããŸãã¯ãviewerãïŒãåºæºãšããŠäžããããŸãã
ã³ã³ãããŒã©ãŒã®ããŒãºããlocalãåç §ç©ºéã§ååŸããå Žåãããã¯æ¢ã«ã³ã³ãããŒã©ãŒã«ä»®æ³ãªããžã§ã¯ããåãä»ããïŒäŸïŒä»®æ³ããŒã«ãæã€ïŒããã®ã¢ãã«è¡åãäœæããããã«çŽæ¥äœ¿çšã§ãã圢åŒã«ãªã£ãŠããŸãã
// Assuming you have an XRInputSource for a controller
const controllerPose = frame.getController(inputSource);
if (controllerPose) {
const controllerMatrix = glMatrix.mat4.fromArray(glMatrix.mat4.create(), controllerPose.matrix);
// This controllerMatrix is already in 'local' or 'viewer' space,
// effectively acting as a model matrix for objects attached to the controller.
}
èŠç·ã€ã³ã¿ã©ã¯ã·ã§ã³ïŒ
ãŠãŒã¶ãŒãäœãèŠãŠãããã倿ããã«ã¯ããã°ãã°ã¬ã€ãã£ã¹ãã£ã³ã°ãé¢ãããŸãããŠãŒã¶ãŒãèŠã€ããŠããæ¹åã«ãã«ã¡ã©ã®åç¹ããã¬ã€ããã£ã¹ãããŸãã
ã¬ã€ã®åç¹ãšæ¹åã¯ããã¥ãŒè¡åãšå°åœ±è¡åã®éè¡åã䜿çšããŠã«ã¡ã©ã®ããŒã«ã«åæ¹ãã¯ãã«ã倿ããããã¯ãŒã«ã空éå ã®ã«ã¡ã©ã®å€æã䜿çšããŠèšç®ã§ããŸãã
ããçŽæ¥çãªã¢ãããŒãã¯ãXRViewerPoseã䜿çšããããšã§ãïŒ
åç®ã®ãã¥ãŒã«å¯ŸããŠïŒ
- ã¯ãŒã«ã空éã«ãããã«ã¡ã©ã®äœçœ®ã¯ã
viewMatrixã®éè¡åããå°åºã§ããŸãã - ã«ã¡ã©ã®åæ¹æ¹åïŒã¯ãŒã«ã空éå
ïŒã¯ã
viewMatrixã®éè¡åã®3çªç®ã®åããïŒãŸãã¯ãã«ã¡ã©ã®ããŒã«ã«ç©ºéã®Z軞ãéãã¥ãŒè¡åã§å€æããŠïŒå°åºã§ããŸãã
const inverseViewMatrix = glMatrix.mat4.invert(glMatrix.mat4.create(), viewMatrix);
const cameraPosition = glMatrix.mat4.getTranslation(vec3.create(), inverseViewMatrix);
// The forward direction is often the negative Z-axis in view space, so it will be
// a vector pointing along the negative Z axis in world space after transformation by the inverse view matrix.
// A simpler way: The camera's local forward vector (0, 0, -1) transformed by the inverse view matrix.
const cameraForward = glMatrix.vec3.create();
glMatrix.vec3.transformMat4(cameraForward, [0, 0, -1], inverseViewMatrix);
glMatrix.vec3.normalize(cameraForward, cameraForward);
ãã®ã¬ã€ã¯ãã¯ãŒã«ãå ã®ãªããžã§ã¯ããšã®äº€å·®å€å®ã«äœ¿çšã§ããŸãã
座æšç³»ã®èŠçŽãšã°ããŒãã«ãªäžè²«æ§
ç°ãªãã°ã©ãã£ãã¯ã¹APIããšã³ãžã³ãããã«ã¯ã©ã€ãã©ãªéã§ãããã«ç°ãªãããšããã座æšç³»ã®èŠçŽã«æ³šæããããšãéèŠã§ããWebXRãšWebGLã§æãäžè¬çãªèŠçŽã¯æ¬¡ã®ãšããã§ãïŒ
- å³æåº§æšç³»ïŒX軞ã¯å³ãY軞ã¯äžãZ軞ã¯ç»é¢ããæåïŒãŸãã¯ãã¥ãŒã¢ããé ãããæ¹åïŒãæããŸããããã¯OpenGLãã²ããŠã¯WebGL/WebXRã®æšæºã§ãã
- Y-upïŒY軞ã¯äžè²«ããŠãäžãæ¹åã«äœ¿çšãããŸãã
- åæ¹æ¹åïŒå€ãã®å Žåããã¥ãŒç©ºéã§ã¯è² ã®Z軞ã§ãã
ã°ããŒãã«ãªã¢ããªã±ãŒã·ã§ã³ã§ã¯ãäžè²«æ§ãä¿ã€ããšãæãéèŠã§ããããèŠçŽã䜿çšããŠã¢ããªã±ãŒã·ã§ã³ãéçºããå¥ã®èŠçŽãæåŸ ããå¯èœæ§ã®ãããŠãŒã¶ãŒïŒçŸä»£ã®XRã§ã¯çšã§ããïŒã«å±éããå Žåã远å ã®å€æãé©çšããå¿ èŠããããããããŸãããããããWebGL/WebXRã§äœ¿çšããã峿Y-upã·ã¹ãã ã®ãããªç¢ºç«ãããæšæºã«åºå·ããããšããåºç¯ãªäºææ§ã®ããã«äžè¬çã«æãå®å šãªæ¹æ³ã§ãã
åœéåã«é¢ããèæ ®äºé ïŒ
- åäœïŒã¡ãŒãã«ãXRã«ããã空éåäœã®äºå®äžã®æšæºã§ãããããã¥ã¡ã³ãã§ãããæèšããããšã§æ··ä¹±ãé²ãããšãã§ããŸããã¢ããªã±ãŒã·ã§ã³ãå®äžçã®æž¬å®ïŒäŸïŒARãªãŒããŒã¬ã€ïŒã«é¢ããå Žåãã¹ã±ãŒã«ãæ£ããè§£éãããããšãä¿èšŒããããšãäžå¯æ¬ ã§ãã
- åãïŒãäžãæ¹åã¯3Dã°ã©ãã£ãã¯ã¹ã§ã¯äžè¬çã«äžè²«ããŠããŸãããããããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ãŒã¹èŠçŽ ãããã²ãŒã·ã§ã³ã®ã¡ã¿ãã¡ãŒã¯æåçãªé©å¿ãå¿ èŠã«ãªãå ŽåããããŸãã
- åç §ç©ºéïŒWebXRã¯ããŸããŸãªåç §ç©ºéïŒ'viewer', 'local', 'bounded-floor', 'unbounded'ïŒãæäŸããŸããããããã°ããŒãã«ã«ãŠãŒã¶ãŒã®æåŸ ã«ã©ã®ããã«ãããã³ã°ãããããçè§£ããããšãéèŠã§ããäŸãã°ããbounded-floorãã¯æ¢ç¥ã®ç©ççãªåºãæå³ããããã¯äžè¬çã«çè§£ãããŸããããã®å¢çé åã®ã¹ã±ãŒã«ãšå¯žæ³ã¯ç°ãªããŸãã
座æšå€æåé¡ã®ãããã°
3Dã°ã©ãã£ãã¯ã¹ãšXRã«ãããæãäžè¬çãªãã©ã¹ãã¬ãŒã·ã§ã³ã®åå ã®1ã€ã¯ããªããžã§ã¯ããééã£ãå Žæã«ãéããŸã«ããŸãã¯äžæ£ç¢ºãªã¹ã±ãŒã«ã§è¡šç€ºãããããšã§ãããããã¯ã»ãšãã©åžžã«åº§æšå€æã«é¢é£ããåé¡ã§ãã
ããããèœãšã穎ïŒ
- äžæ£ãªè¡åä¹ç®é åºïŒåè¿°ã®éãã
å°åœ± à ãã¥ãŒ à ã¢ãã«ã®é åºã¯éåžžã«éèŠã§ãããããå ¥ãæ¿ãããšãäºæãã¬çµæã«ã€ãªããå¯èœæ§ããããŸãã - äžæ£ãªè¡åã®åæåïŒåäœè¡åã§å§ããããšã¯éåžžæ£ããã§ããããããå¿ããããè¡åãäžé©åã«å€æŽããããããšåé¡ãåŒãèµ·ããå¯èœæ§ããããŸãã
- `XRReferenceSpace`ã®èª€ã£ãè§£éïŒãviewerããšãlocalãåç §ç©ºéã®éããçè§£ããŠããªããšããªããžã§ã¯ããééã£ãåç¹ãåºæºã«è¡šç€ºãããããšããããŸãã
- ã·ã§ãŒããŒãžã®è¡åéä¿¡å¿ãïŒå€æã¯GPUäžã§è¡ãããŸããèšç®ãããè¡åãã·ã§ãŒããŒã«éãããé ç¹äœçœ®ã«é©çšãããªãéãããªããžã§ã¯ãã¯å€æãããŸããã
- å·Šæç³»ãšå³æç³»ã®äžäžèŽïŒç°ãªãèŠçŽã§äœæãããã¢ã»ãããã€ã³ããŒãããããç°ãªãèŠçŽã®ã©ã€ãã©ãªã䜿çšããããããšãåãã®åé¡ãçºçããå¯èœæ§ããããŸãã
ãããã°ææ³ïŒ
- 座æšè»žã®å¯èŠåïŒã¯ãŒã«ã空éã®åç¹ããªããžã§ã¯ãã®åç¹ãã«ã¡ã©ã®äœçœ®ã«ãå°ããªè²ä»ãã®è»žãŠã£ãžã§ããïŒX軞ã¯èµ€ãY軞ã¯ç·ãZ軞ã¯éïŒãã¬ã³ããªã³ã°ããŸããããã«ãããå空éã®åããèŠèŠçã«ç¢ºèªã§ããŸãã
- è¡åã®å€ã®åºåïŒããŸããŸãªæ®µéã§ã¢ãã«ããã¥ãŒãå°åœ±è¡åã®å€ããã°ã«åºåããŸãããããã調ã¹ãŠãæå³ãã倿ãåæ ããŠãããã©ããã確èªããŸãã
- åçŽåïŒè€éããåãé€ããŸããåäžã®ç«æ¹äœããå§ãããããåç¹ã«é 眮ããæ£ããã¬ã³ããªã³ã°ãããããšã確èªããŸãããã®åŸãåŸã ã«å€æããªããžã§ã¯ãã远å ããŠãããŸãã
- XRãããã¬ã®äœ¿çšïŒäžéšã®XRéçºç°å¢ããã©ãŠã¶æ¡åŒµæ©èœã«ã¯ãã·ãŒã³ã°ã©ãããªããžã§ã¯ãã«é©çšãããå€æãæ€æ»ããããŒã«ãæäŸãããŠããŸãã
- æ°åŠã®ç¢ºèªïŒã«ã¹ã¿ã ã®è¡åæŒç®ã䜿çšããŠããå Žåã¯ãgl-matrixã®ãããªæšæºã©ã€ãã©ãªã«å¯ŸããŠå®è£ ãå確èªããŠãã ããã
空éã³ã³ãã¥ãŒãã£ã³ã°ãšå€æã®æªæ¥
WebXRãæçããã«ã€ããŠã座æšå€æã®åºæ¬ååã¯åŒãç¶ãåºç€ãšãªããŸãããããããããã®å€æãæäœã管çããæ¹æ³ã¯é²åãããããããŸããïŒ
- ããé«ã¬ãã«ãªæœè±¡åïŒãã¬ãŒã ã¯ãŒã¯ããšã³ãžã³ïŒA-Frame, Babylon.js, Three.jsãªã©ïŒã¯ãæ¢ã«ãã®è€éãã®å€ããæœè±¡åããŠããããšã³ãã£ãã£ã®äœçœ®æ±ºããæ¹åä»ãã®ããã®çŽæçãªã³ã³ããŒãã³ãããŒã¹ã®ã·ã¹ãã ãæäŸããŠããŸãã
- AIæ¯æŽã®ç©ºéã¢ã³ã«ãŒïŒå°æ¥ã®ã·ã¹ãã ã¯ã座æšå€æãšç©ºéã¢ã³ã«ãŒãèªåçã«ç®¡çããæåã§ã®è¡åæäœãªãã«ãçŸå®äžçã«ä»®æ³ãªããžã§ã¯ããé 眮ããæ°žç¶ãããããšã容æã«ãªããããããŸããã
- ã¯ãã¹ãã©ãããã©ãŒã ã®äžè²«æ§ïŒXRããŒããŠã§ã¢ã倿§åããã«ã€ããŠãç°ãªãããã€ã¹ããã©ãããã©ãŒã éã§ã·ãŒã ã¬ã¹ãªå€æãä¿èšŒããããšãããã«éèŠã«ãªããå ç¢ã§æç¢ºã«å®çŸ©ãããæšæºãèŠæ±ãããããã«ãªããŸãã
çµè«
座æšç³»å€æã¯ãWebXRã«ããããã¹ãŠã®3D空éã³ã³ãã¥ãŒãã£ã³ã°ãšæ²¡å ¥äœéšãæ§ç¯ãããåºç€ã§ããããŒã«ã«ãã¯ãŒã«ãããã¥ãŒã¹ããŒã¹ã®æç¢ºãªåœ¹å²ãçè§£ããç¹ã«è¡å倿ã©ã€ãã©ãªïŒgl-matrixãªã©ïŒã®å©ããåããŠå€æè¡åã®äœ¿çšãç¿åŸããããšã§ãéçºè ã¯ä»®æ³ç°å¢ã粟å¯ã«å¶åŸ¡ã§ããããã«ãªããŸãã
ããããªåžå Žåãã«æ§ç¯ããŠããå Žåã§ããã°ããŒãã«ãªãªãŒãã£ãšã³ã¹ãç®æããŠããå Žåã§ãããããã®ç©ºéæŠå¿µã®æ·±ãçè§£ã¯ãããå®å®ããäºæž¬å¯èœã§ãæçµçã«ã¯ããé åçã§ä¿¡ææ§ã®ããXRã¢ããªã±ãŒã·ã§ã³ãäœæããåãäžããŠãããŸããæ°åŠãåãå ¥ãã倿ãèŠèŠåããäžåºŠã«äžã€ã®åº§æšã§ãæ²¡å ¥äœéšã®æªæ¥ãç¯ãäžããŸãããã